// Regular expression used to split reply strings
var replySplitter = /\s+/;

function Requests() {}

Requests.prototype.reply = function (replies, callback, context) {
	var cache, reply;
	if (!callback) return this;

	cache = this.__replies || (this.__replies = {});
	replies = replies.split(replySplitter);

	while ((reply = replies.shift())) {
		cache[reply] = {
			callback,
			context
		};
	}

	return this;
};

Requests.prototype.request = function (reply) {
	var i, len, rest = [];

	reply = this.__replies && this.__replies[reply];

	if (!reply) {
		return;
	}

	// Fill up `rest` with the callback arguments.  Since we're only copying
	// the tail of `arguments`, a loop is much faster than Array#slice.
	for (i = 1, len = arguments.length; i < len; i++) {
		rest[i - 1] = arguments[i];
	}

	return reply.callback.apply(reply.context || this, rest);
};

// Set up a handler that can only be requested once
Requests.prototype.replyOnce = function (replies, callback, context) {
	var self = this;

	var cb = function () {
		self.stopReplying(replies, cb);
		callback.apply(context || self, arguments);
	};

	return this.on(events, cb, context);
};

Requests.prototype.stopReplying = function (replies, callback, context) {
	var cache, replay, item;

	// No replies, or removing *all* replies.
	if (!(cache = this.__replies)) return this;
	if (!(replies || callback || context)) {
		delete this.__replies;
		return this;
	}

	replies = replies ? replies.split(replySplitter) : keys(cache);

	// Loop through the callback item, splicing where appropriate.
	while ((replay = replies.shift())) {
		item = cache[replay];
		if (!item) continue;

		if (
			(!callback || (callback === item.callback)) &&
			(!context || (context === item.context))
			) {
			delete cache[name];
		}
	}

	return this;
};

module.exports = Requests;


// Helpers
// -------

var keys = Object.keys;
